package events;

import collaboration.*;
import org.omg.CORBA.*;

public class Event {
	private EventNode event[]; /**< Estructura que modela un evento */
	public static final int DEFAULT_EVENT_TYPE = 0;
	
	/**
	 * Constructor por defecto. Crea un campo llamado "type",
	 * cuyo valor inicial es el definido por DEFAULT_EVENT_TYPE.
	 */
	public Event()
	{
		event = new EventNode[0];
		
		member_value("type", DEFAULT_EVENT_TYPE);
	}
	
	/**
	 * Posicion de un campo del evento
	 *
	 * @param name Nombre del campo
	 * @return Posicion del campo o -1 si no existe
	 */
	private int member_pos(String name)
	{
		int i;
		for (i=0; i<event.length; i++)
		{
			if (name.equals(event[i].name))
			{
				return i;
			}
		}
		
		return -1;
	}
	
	/**
	 * Crea un nuevo campo de tipo generico para el evento
	 *
	 * @param name Nombre del campo
	 * @param value Valor del campo
	 */
	private void create_member(String name, Any value)
	{	
		int size = event.length+1;
		EventNode[] ev = new EventNode[size];
		
		for (int i=0; i<event.length; i++)
			ev[i] = event[i];
		
		ev[event.length] = new EventNode(name, value);
		
		event = ev;
	}
	
	/**
	 * Comprueba si un campo existe o no en el evento
	 *
	 * @param name Nombre del campo
	 * @return True si el campo existe. False en caso contrario.
	 */
	public boolean exists_member(String name)
	{
		if (member_pos(name) != -1)
			return true;
		else return false;
	}
	
	/**
	 * Obtiene el valor de un campo (si existe)
	 *
	 * @param name Nombre del campo
	 * @return Tipo generico que modela el valor del campo especificado o
	 *         valor nulo si el campo no existe
	 */
	public Any member_value(String name)
	{
		int pos = member_pos(name);
		if (pos != -1)
		{
			return event[pos].value;
		}
		else
		{
			return null;
		}
	}
	
	/**
	 * Obtiene el valor de un campo (si existe)
	 *
	 * @param name Nombre del campo
	 * @return Valor del campo especificado o
	 *         valor nulo (Float.MIN_VALUE) si el campo no existe
	 */
	public float float_member_value(String name)
	{
		int pos = member_pos(name);
		if (pos != -1)
		{
			Any a = event[pos].value;
			return a.extract_float();
		}
		else
		{
			return Float.MIN_VALUE;
		}
	}
	
	/**
	 * Obtiene el valor de un campo (si existe)
	 *
	 * @param name Nombre del campo
	 * @return Valor del campo especificado o
	 *         valor nulo (Double.MIN_VALUE) si el campo no existe
	 */
	public double double_member_value(String name)
	{
		int pos = member_pos(name);
		if (pos != -1)
		{
			Any a = event[pos].value;
			return a.extract_double();
		}
		else
		{
			return Double.MIN_VALUE;
		}
	}
	
	/**
	 * Obtiene el valor de un campo (si existe)
	 *
	 * @param name Nombre del campo
	 * @return Valor del campo especificado o
	 *         valor nulo (Integer.MIN_VALUE) si el campo no existe
	 */
	public int int_member_value(String name)
	{
		int pos = member_pos(name);
		if (pos != -1)
		{
			Any a = event[pos].value;
			return a.extract_long();
		}
		else
		{
			return Integer.MIN_VALUE;
		}
	}
	
	/**
	 * Obtiene el valor de un campo (si existe)
	 *
	 * @param name Nombre del campo
	 * @return Valor del campo especificado o
	 *         valor nulo (Long.MIN_VALUE) si el campo no existe
	 */
	public long long_member_value(String name)
	{
		int pos = member_pos(name);
		if (pos != -1)
		{
			Any a = event[pos].value;
			return a.extract_longlong();
		}
		else
		{
			return Long.MIN_VALUE;
		}
	}
	
	/**
	 * Obtiene el valor de un campo (si existe)
	 *
	 * @param name Nombre del campo
	 * @return Valor del campo especificado o
	 *         valor null si el campo no existe
	 */
	public String string_member_value(String name)
	{
		int pos = member_pos(name);
		if (pos != -1)
		{
			Any a = event[pos].value;
			return a.extract_string();
		}
		else
		{
			return null;
		}
	}
	
	/**
	 * Asigna un valor a un campo (crea el campo si no existe)
	 *
	 * @param name Nombre del campo
	 * @param value Valor para el campo
	 */
	public void member_value(String name, Any value)
	{
		int pos = member_pos(name);
		if (pos != -1)
		{
			event[pos].value = value;
		}
		else
		{
			create_member(name, value);
		}
	}
	
	/**
	 * Asigna un valor a un campo (crea el campo si no existe)
	 *
	 * @param name Nombre del campo
	 * @param value Valor para el campo
	 */
	public void member_value(String name, int value)
	{
		int pos = member_pos(name);
		if (pos != -1)
		{
			event[pos].value.insert_long(value);
		}
		else
		{
			Any data = org.omg.CORBA.ORB.init().create_any();
			data.insert_long(value);
			create_member(name, data);
		}
	}
	
	/**
	 * Asigna un valor a un campo (crea el campo si no existe)
	 *
	 * @param name Nombre del campo
	 * @param value Valor para el campo
	 */
	public void member_value(String name, long value)
	{
		int pos = member_pos(name);
		if (pos != -1)
		{
			event[pos].value.insert_longlong(value);
		}
		else
		{
			Any data = org.omg.CORBA.ORB.init().create_any();
			data.insert_longlong(value);
			create_member(name, data);
		}
	}
	
	/**
	 * Asigna un valor a un campo (crea el campo si no existe)
	 *
	 * @param name Nombre del campo
	 * @param value Valor para el campo
	 */
	public void member_value(String name, float value)
	{
		int pos = member_pos(name);
		if (pos != -1)
		{
			event[pos].value.insert_float(value);
		}
		else
		{
			Any data = org.omg.CORBA.ORB.init().create_any();
			data.insert_float(value);
			create_member(name, data);
		}
	}
	
	/**
	 * Asigna un valor a un campo (crea el campo si no existe)
	 *
	 * @param name Nombre del campo
	 * @param value Valor para el campo
	 */
	public void member_value(String name, double value)
	{
		int pos = member_pos(name);
		if (pos != -1)
		{
			event[pos].value.insert_double(value);
		}
		else
		{
			Any data = org.omg.CORBA.ORB.init().create_any();
			data.insert_double(value);
			create_member(name, data);
		}
	}
	
	/**
	 * Asigna un valor a un campo (crea el campo si no existe)
	 *
	 * @param name Nombre del campo
	 * @param value Valor para el campo
	 */
	public void member_value(String name, String value)
	{
		int pos = member_pos(name);
		if (pos != -1)
		{
			event[pos].value.insert_string(value);
		}
		else
		{
			Any data = org.omg.CORBA.ORB.init().create_any();
			data.insert_string(value);
			create_member(name, data);
		}
	}
	
	/**
	 * Cuenta el numero de campos del evento
	 *
	 * @return Numero de campos del evento
	 */
	public int count_members()
	{
		return event.length;
	}
	
	/**
	 * Obtiene el tipo concreto del evento
	 *
	 * @return Tipo del evento definido por el campo "type".
	 */
	public int get_type()
	{
		Any a = member_value("type");
		return a.extract_long();
	}
	
	/**
	 * Convierte el evento en un objeto generico
	 *
	 * @param data Variable generica donde se guardara el evento
	 */
	public Any to_any()
	{
		Any a = org.omg.CORBA.ORB.init().create_any();
		EventHelper.insert(a, event);
		
		return a;
	}
	
	/**
	 * Extrae un evento de un objeto generico
	 *
	 * @param data Variable generica desde donde se extrae el evento
	 */
	public void from_any(Any data)
	{
		event = EventHelper.extract(data);
	}
}
